//Copyright (C) 2010 Ron Coleman. Contact: ronncoleman@gmail.com
//
//This library is free software; you can redistribute it and/or
//modify it under the terms of the GNU General Public License
//as published by the Free Software Foundation; either
//version 3 of the License, or (at your option) any later version.
//
//This library is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with this library; if not, write to the Free Software
//Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

/*
 * ElogEditDialog.java
 *
 * Created on Nov 13, 2010, 10:40:18 AM
 */
package org.workplicity.cia.ui;

import java.awt.Frame;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Set;
import javax.swing.JDialog;
import javax.swing.JOptionPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
import org.workplicity.cia.table.CommentsTableModel;
import org.workplicity.cia.table.render.BaseTableRenderer;
import org.workplicity.cia.table.LinksTableModel;
import org.workplicity.cia.table.render.CommentsTableRenderer;
import org.workplicity.cia.table.render.LinksTableRenderer;
import org.workplicity.cia.util.CIAHelper;
import org.workplicity.cia.worklet.ElogsWorklet;
import org.workplicity.elog.entry.Audit;
import org.workplicity.elog.entry.Elog;
import org.workplicity.elog.entry.ElogUser;
import org.workplicity.elog.entry.Handoff;
import org.workplicity.elog.entry.Link;
import org.workplicity.elog.entry.Trade;
import org.workplicity.elog.repos.Handoffs;
import org.workplicity.elog.repos.Links;
import org.workplicity.entry.Comment;
import org.workplicity.entry.User;
import org.workplicity.util.DateFormatter;
import org.workplicity.util.Helper;
import org.workplicity.worklet.WorkletContext;

/**
 * This class implements the elog entry dialog.
 * @author Ron Coleman
 */
public class ElogEditDialog extends javax.swing.JDialog {
    private Elog elog = null;
    
    private final ElogUser owner;

    private WorkletContext context = WorkletContext.getInstance();

    private ElogUser me = (ElogUser) Helper.whoAmI(context);

    private ArrayList<Audit> trail = new ArrayList<Audit>( );

    private Handoff handoff = new Handoff();

    /**
     * Flags if the elog needs to be written a second
     * time to the repository.
     */
    private boolean dirty = false;

    /** Creates new form ElogEditDialog */
    public ElogEditDialog(Frame parent, ElogUser owner, Elog elog) {
        super(parent, true);
        initComponents();

        this.owner = owner;

        init(elog);
    }

    /**
     * Constructor to enable this dialog to open dialogs
     * of itself through the links panel.
     * @param parent Parent
     * @param elog Elog
     */
    public ElogEditDialog(JDialog parent, ElogUser owner, Elog elog) {
        super(parent, true);
        initComponents();

        this.owner = owner;

        init(elog);
    }

    private void init(Elog elog)
    {
        this.setLocationRelativeTo(null);
        
        this.setTitle("Netlog (" + me.getLogname() + ") >> " +
                (elog.getId()==-1 ? "Create" : "Update"));

        this.elog = elog;

        formatCommentsTable();

        formatLinksTable();

        initElog();

    }

    private void formatCommentsTable() {
        this.commentTextArea.setText("");
        
        this.commentsTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);

        CommentsTableModel model = (CommentsTableModel) this.commentsTable.getModel();

        model.setComments(elog.getComments());

        final int[] WIDTHS = {
            90,  // Date
            75,  // User
           500   // Comment
        };

        for (int i = 0; i < WIDTHS.length; i++) {
            TableColumn col = commentsTable.getColumnModel().getColumn(i);

            col.setPreferredWidth(WIDTHS[i]);
        }

        TableColumnModel cm = this.commentsTable.getColumnModel();

        // Custom renderer for the other fields.
        CommentsTableRenderer cr = new CommentsTableRenderer();

        for (int i = 0; i < commentsTable.getColumnCount(); i++) {
            cm.getColumn(i).setCellRenderer(cr);
        }

        // Add mouse support for the request table
        // See http://mycodepage.blogspot.com/2006/09/how-to-create-double-click-event-on.html
        commentsTable.addMouseListener(new MouseAdapter() {

            @Override
            public void mouseClicked(MouseEvent e) {
                if (e.getClickCount() == 2) {
                    JTable target = (JTable) e.getSource();

                    final int row = target.getSelectedRow();

                    SwingUtilities.invokeLater(new Runnable() {
                        public void run() {
                            viewComment(row);
                        }
                    });
                }
            }
        });
    }

    private void formatLinksTable() {

        this.linksTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);

        final int[] WIDTHS = {
            20,  // Link state
            40,  // Log id
            90,  // Update date
            75,  // User
           240   // Description
        };

        for (int i = 0; i < WIDTHS.length; i++) {
            TableColumn col = linksTable.getColumnModel().getColumn(i);

            col.setPreferredWidth(WIDTHS[i]);
        }

        TableColumnModel cm = this.linksTable.getColumnModel();

        // Customer renderer for the link check box
        LinksTableRenderer cr0 = new LinksTableRenderer();

        // Custom renderer for the other fields.
        BaseTableRenderer crn = new BaseTableRenderer();

        for (int i = 0; i < linksTable.getColumnCount(); i++) {
            if(i == 0)
                cm.getColumn(i).setCellRenderer(cr0);
            else
                cm.getColumn(i).setCellRenderer(crn);
        }

        // Add mouse support for the request table
        // See http://mycodepage.blogspot.com/2006/09/how-to-create-double-click-event-on.html
        linksTable.addMouseListener(new MouseAdapter() {

            @Override
            public void mouseClicked(MouseEvent e) {
                if (e.getClickCount() == 2) {
                    JTable target = (JTable) e.getSource();
                    
                    final int row = target.getSelectedRow();

                    SwingUtilities.invokeLater(new Runnable() {
                        public void run() {
                            editEntry(row);
                        }
                    });
                }
            }
        });
    }

    private void viewComment(int row) {
        CommentsTableModel model = (CommentsTableModel) this.commentsTable.getModel();

        Comment comment = model.getComments().get(row);

        CommentPopupDialog dialog = new CommentPopupDialog(this,comment);

        dialog.setVisible(true);
    }

    private void editEntry(int row) {
        LinksTableModel model = (LinksTableModel) linksTable.getModel();

        Elog alog = model.getRow(row);
        ElogUser user = model.getOwner(row);

        ElogEditDialog dialog = new ElogEditDialog(this, user, alog);

        dialog.setVisible(true);
    }

    /**
     * Initializes the elog using defaults or the input info.
     */
    private void initElog() {
        // If this is a new log entry, set the create user
        // to me and the elog to point to mine
        if (elog.getId() == -1) {
            elog.setCreateUserId(me.getId());

            elog.setReposTitle(me.getReposTitle());
        }

        // Set the owner of the log
        this.ownerTextField.setText(owner + "");

        if(elog.getId() != -1)
            this.idTextField.setText(elog.getId()+"");
        else
            this.idTextField.setText("N/A");

        this.descriptionTextArea.setText(elog.getDescription());
        this.workDoneTextArea.setText(elog.getWorkDone());
        this.workOrderTextField.setText(elog.getRequestId());

        this.statusComboBox.addItem(Elog.Status.NOTDONE);
        this.statusComboBox.addItem(Elog.Status.DONE);

        this.statusComboBox.setSelectedItem(elog.getStatus());

        if (elog.getType() == Elog.Type.UNUSUAL) {
            this.typeCheckBox.setSelected(true);
        }

        // If this is NOT a new log entry, disable appropriate fields for update
        if(elog.getId() != -1) {
            this.descriptionTextArea.setEnabled(false);
            this.workDoneTextArea.setEnabled(false);
            this.workOrderTextField.setEnabled(false);

            // If I'm not the owner, I can't change its status
            if(!me.getReposTitle().equals(elog.getReposTitle()))
                this.statusComboBox.setEnabled(false);
        }

        // Create the users drop-down
        ArrayList<User> users = ElogsWorklet.getInstance().getUsersCache().getCache();

        Collections.sort(users, new Comparator() {
            public int compare(Object o1, Object o2) {
                String u1 = ((User) o1).getLogname();
                String u2 = ((User) o2).getLogname();
                return u1.compareTo(u2);
            }
        });

        for (User user : users) {
            // Assuming...the user can write a handoff to himself/herself
//            if (user.getId().equals(me.getId())) {
//                continue;
//            }

            this.userLinkComboBox.addItem(user);
            this.userHandoffComboBox.addItem(user);
        }

        // Create the trades drop-down
        ArrayList<Trade> trades = ElogsWorklet.getInstance().getTrades().getCache();

        Collections.sort(trades, new Comparator() {
            public int compare(Object o1, Object o2) {
                String u1 = ((Trade) o1).getName();
                String u2 = ((Trade) o2).getName();
                return u1.compareTo(u2);
            }
        });

        for (Trade trade : trades) {
            this.tradeHandoffComboBox.addItem(trade);
        }

        // Set the handoff user and trade if this elog points to a handoff
        String criteria = "/list [ fromId = " + owner.getId() + " and elogId = " + elog.getId() + " ]";

        ArrayList<Handoff> handoffs = Helper.query(Handoffs.TITLE, criteria, context);

        if(!handoffs.isEmpty()) {
            handoff = (Handoff) handoffs.get(0);

            Integer toId = handoff.getToId();
            Integer toTradeId = handoff.getTradeId();

            if(toId != -1) {
                ElogUser toUser = CIAHelper.toUser(toId,users);
                this.userHandoffComboBox.setSelectedItem(toUser);
//                this.userHandoffComboBox.removeAllItems();
//                this.userHandoffComboBox.addItem(toUser);
            }

            if(toTradeId != -1) {
                Trade toTrade = CIAHelper.toTrade(toTradeId);
               // .setSelectedItem(toTrade) ought to work but...it doesn't
                this.tradeHandoffComboBox.removeAllItems();
                this.tradeHandoffComboBox.addItem(toTrade);
            }

            this.handoffMessageTextArea.setText((handoff.getMessage()));

            this.handoffDateTextField.setText(DateFormatter.toString(handoff.getUpdateDate()));

            this.handoffIdTextField.setText(handoff.getId() + "");

            this.userHandoffComboBox.setEnabled(false);
            this.tradeHandoffComboBox.setEnabled(false);
            this.handoffMessageTextArea.setEditable(false);
        }
        else
        {
            this.handoffIdTextField.setText("NA");
            this.handoffDateTextField.setText("NA");
        }

        // Refresh the links table
        LinksTableModel model = (LinksTableModel) this.linksTable.getModel();
        model.refresh(elog);
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        cancelButton = new javax.swing.JButton();
        saveButton = new javax.swing.JButton();
        jTabbedPane1 = new javax.swing.JTabbedPane();
        jPanel1 = new javax.swing.JPanel();
        jLabel1 = new javax.swing.JLabel();
        workOrderTextField = new javax.swing.JTextField();
        jLabel2 = new javax.swing.JLabel();
        jScrollPane3 = new javax.swing.JScrollPane();
        descriptionTextArea = new javax.swing.JTextArea();
        typeCheckBox = new javax.swing.JCheckBox();
        jLabel3 = new javax.swing.JLabel();
        jScrollPane4 = new javax.swing.JScrollPane();
        workDoneTextArea = new javax.swing.JTextArea();
        statusComboBox = new javax.swing.JComboBox();
        jPanel2 = new javax.swing.JPanel();
        addLinkButton = new javax.swing.JButton();
        jScrollPane2 = new javax.swing.JScrollPane();
        linksTable = new javax.swing.JTable();
        jLabel7 = new javax.swing.JLabel();
        userLinkComboBox = new javax.swing.JComboBox();
        jPanel3 = new javax.swing.JPanel();
        jLabel4 = new javax.swing.JLabel();
        handoffIdTextField = new javax.swing.JTextField();
        jLabel10 = new javax.swing.JLabel();
        handoffDateTextField = new javax.swing.JTextField();
        jLabel11 = new javax.swing.JLabel();
        jScrollPane7 = new javax.swing.JScrollPane();
        handoffMessageTextArea = new javax.swing.JTextArea();
        jPanel6 = new javax.swing.JPanel();
        jLabel6 = new javax.swing.JLabel();
        userHandoffComboBox = new javax.swing.JComboBox();
        tradeHandoffComboBox = new javax.swing.JComboBox();
        jLabel5 = new javax.swing.JLabel();
        jPanel4 = new javax.swing.JPanel();
        jScrollPane1 = new javax.swing.JScrollPane();
        commentsTable = new javax.swing.JTable();
        addCommentButton = new javax.swing.JButton();
        jScrollPane6 = new javax.swing.JScrollPane();
        commentTextArea = new javax.swing.JTextArea();
        jPanel5 = new javax.swing.JPanel();
        jScrollPane5 = new javax.swing.JScrollPane();
        jTable3 = new javax.swing.JTable();
        jLabel8 = new javax.swing.JLabel();
        ownerTextField = new javax.swing.JTextField();
        jLabel9 = new javax.swing.JLabel();
        idTextField = new javax.swing.JTextField();
        jComboBox1 = new javax.swing.JComboBox();
        jComboBox2 = new javax.swing.JComboBox();
        jComboBox3 = new javax.swing.JComboBox();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);

        cancelButton.setFont(new java.awt.Font("Tahoma", 0, 12));
        cancelButton.setText("Cancel");
        cancelButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cancelButtonActionPerformed(evt);
            }
        });

        saveButton.setFont(new java.awt.Font("Tahoma", 0, 12));
        saveButton.setText("Save");
        saveButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                saveButtonActionPerformed(evt);
            }
        });

        jLabel1.setFont(new java.awt.Font("Tahoma", 0, 12));
        jLabel1.setText("Work order:");

        workOrderTextField.setFont(new java.awt.Font("Tahoma", 0, 12));

        jLabel2.setFont(new java.awt.Font("Tahoma", 0, 12));
        jLabel2.setText("Job description:");

        descriptionTextArea.setColumns(20);
        descriptionTextArea.setRows(5);
        descriptionTextArea.setText("The text for the job description is written in here.");
        jScrollPane3.setViewportView(descriptionTextArea);

        typeCheckBox.setFont(new java.awt.Font("Tahoma", 0, 12));
        typeCheckBox.setText("Unusual");

        jLabel3.setFont(new java.awt.Font("Tahoma", 0, 12));
        jLabel3.setText("Work done:");

        workDoneTextArea.setColumns(20);
        workDoneTextArea.setRows(5);
        workDoneTextArea.setText("The text for the work actually done is written in here.");
        jScrollPane4.setViewportView(workDoneTextArea);

        statusComboBox.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(jScrollPane4, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 355, Short.MAX_VALUE)
                    .addComponent(jScrollPane3, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 355, Short.MAX_VALUE)
                    .addGroup(javax.swing.GroupLayout.Alignment.LEADING, jPanel1Layout.createSequentialGroup()
                        .addComponent(jLabel1)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(workOrderTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 88, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(statusComboBox, 0, 102, Short.MAX_VALUE)
                        .addGap(18, 18, 18)
                        .addComponent(typeCheckBox))
                    .addComponent(jLabel2, javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jLabel3, javax.swing.GroupLayout.Alignment.LEADING))
                .addContainerGap())
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel1)
                    .addComponent(workOrderTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(typeCheckBox)
                    .addComponent(statusComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jLabel2)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jScrollPane3, javax.swing.GroupLayout.PREFERRED_SIZE, 87, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jLabel3)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jScrollPane4, javax.swing.GroupLayout.DEFAULT_SIZE, 99, Short.MAX_VALUE)
                .addContainerGap())
        );

        jTabbedPane1.addTab("", new javax.swing.ImageIcon(getClass().getResource("/book_twocolor.png")), jPanel1, "Input electronic log information."); // NOI18N

        addLinkButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/add2.png"))); // NOI18N
        addLinkButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                addLinkButtonActionPerformed(evt);
            }
        });

        linksTable.setFont(new java.awt.Font("Tahoma", 0, 12));
        linksTable.setModel(new LinksTableModel());
        jScrollPane2.setViewportView(linksTable);

        jLabel7.setFont(new java.awt.Font("Tahoma", 0, 12));
        jLabel7.setText("User:");

        userLinkComboBox.setFont(new java.awt.Font("Tahoma", 0, 12));
        userLinkComboBox.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "--Select--" }));

        javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
        jPanel2.setLayout(jPanel2Layout);
        jPanel2Layout.setHorizontalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel2Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 355, Short.MAX_VALUE)
                    .addGroup(jPanel2Layout.createSequentialGroup()
                        .addGap(155, 155, 155)
                        .addComponent(jLabel7)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(userLinkComboBox, 0, 111, Short.MAX_VALUE)
                        .addGap(10, 10, 10)
                        .addComponent(addLinkButton)))
                .addContainerGap())
        );
        jPanel2Layout.setVerticalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 107, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jPanel2Layout.createSequentialGroup()
                        .addComponent(jLabel7)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 14, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(jPanel2Layout.createSequentialGroup()
                        .addComponent(userLinkComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 8, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addComponent(addLinkButton, javax.swing.GroupLayout.DEFAULT_SIZE, 29, Short.MAX_VALUE))
                .addGap(125, 125, 125))
        );

        jTabbedPane1.addTab("", new javax.swing.ImageIcon(getClass().getResource("/link.png")), jPanel2, "Input additional comments."); // NOI18N

        jLabel4.setFont(new java.awt.Font("Tahoma", 0, 12));
        jLabel4.setText("Id:");

        handoffIdTextField.setEditable(false);
        handoffIdTextField.setText("jTextField1");

        jLabel10.setFont(new java.awt.Font("Tahoma", 0, 12));
        jLabel10.setText("Date:");

        handoffDateTextField.setEditable(false);
        handoffDateTextField.setText("mm / dd / yyyy");

        jLabel11.setFont(new java.awt.Font("Tahoma", 0, 12));
        jLabel11.setText("Message:");

        handoffMessageTextArea.setColumns(20);
        handoffMessageTextArea.setFont(new java.awt.Font("Tahoma", 0, 12));
        handoffMessageTextArea.setRows(5);
        jScrollPane7.setViewportView(handoffMessageTextArea);

        jPanel6.setBorder(javax.swing.BorderFactory.createTitledBorder("Handoff to"));

        jLabel6.setFont(new java.awt.Font("Tahoma", 0, 12));
        jLabel6.setText("User:");

        userHandoffComboBox.setFont(new java.awt.Font("Tahoma", 0, 12));
        userHandoffComboBox.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "-- Select --" }));

        tradeHandoffComboBox.setFont(new java.awt.Font("Tahoma", 0, 12));
        tradeHandoffComboBox.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "-- Select --" }));

        jLabel5.setFont(new java.awt.Font("Tahoma", 0, 12));
        jLabel5.setText("Trade:");

        javax.swing.GroupLayout jPanel6Layout = new javax.swing.GroupLayout(jPanel6);
        jPanel6.setLayout(jPanel6Layout);
        jPanel6Layout.setHorizontalGroup(
            jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel6Layout.createSequentialGroup()
                .addGroup(jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(jLabel6)
                    .addComponent(jLabel5))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(tradeHandoffComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 114, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(userHandoffComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 114, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap(179, Short.MAX_VALUE))
        );
        jPanel6Layout.setVerticalGroup(
            jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel6Layout.createSequentialGroup()
                .addGroup(jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(userHandoffComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel6))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(tradeHandoffComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel5))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3);
        jPanel3.setLayout(jPanel3Layout);
        jPanel3Layout.setHorizontalGroup(
            jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel3Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jPanel3Layout.createSequentialGroup()
                        .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                            .addComponent(jLabel4)
                            .addComponent(jLabel10))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                            .addComponent(handoffIdTextField)
                            .addComponent(handoffDateTextField, javax.swing.GroupLayout.DEFAULT_SIZE, 90, Short.MAX_VALUE))
                        .addGap(235, 235, 235))
                    .addGroup(jPanel3Layout.createSequentialGroup()
                        .addComponent(jLabel11)
                        .addContainerGap(315, Short.MAX_VALUE))
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel3Layout.createSequentialGroup()
                        .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                            .addComponent(jScrollPane7, javax.swing.GroupLayout.DEFAULT_SIZE, 355, Short.MAX_VALUE)
                            .addComponent(jPanel6, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                        .addContainerGap())))
        );
        jPanel3Layout.setVerticalGroup(
            jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel3Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jPanel6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel4)
                    .addComponent(handoffIdTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(handoffDateTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel10))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(jLabel11)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jScrollPane7, javax.swing.GroupLayout.PREFERRED_SIZE, 88, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );

        jTabbedPane1.addTab("", new javax.swing.ImageIcon(getClass().getResource("/walll1.png")), jPanel3); // NOI18N

        commentsTable.setFont(new java.awt.Font("Tahoma", 0, 12));
        commentsTable.setModel(new CommentsTableModel());
        jScrollPane1.setViewportView(commentsTable);

        addCommentButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/add2.png"))); // NOI18N
        addCommentButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                addCommentButtonActionPerformed(evt);
            }
        });

        commentTextArea.setColumns(20);
        commentTextArea.setRows(5);
        jScrollPane6.setViewportView(commentTextArea);

        javax.swing.GroupLayout jPanel4Layout = new javax.swing.GroupLayout(jPanel4);
        jPanel4.setLayout(jPanel4Layout);
        jPanel4Layout.setHorizontalGroup(
            jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel4Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(jScrollPane6, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 355, Short.MAX_VALUE)
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 355, Short.MAX_VALUE)
                    .addComponent(addCommentButton, javax.swing.GroupLayout.Alignment.LEADING))
                .addContainerGap())
        );
        jPanel4Layout.setVerticalGroup(
            jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel4Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 141, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jScrollPane6, javax.swing.GroupLayout.DEFAULT_SIZE, 72, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(addCommentButton, javax.swing.GroupLayout.PREFERRED_SIZE, 31, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );

        jTabbedPane1.addTab("", new javax.swing.ImageIcon(getClass().getResource("/pencil2.png")), jPanel4); // NOI18N

        jTable3.setFont(new java.awt.Font("Tahoma", 0, 12));
        jTable3.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {
                {"11/17/2010", "HVAC", "Sam", "CREATED"},
                {"11/18/2010", "Electrical", "Dave", "LINKED -> 18"}
            },
            new String [] {
                "Date", "Trade", "User", "Action"
            }
        ));
        jScrollPane5.setViewportView(jTable3);

        javax.swing.GroupLayout jPanel5Layout = new javax.swing.GroupLayout(jPanel5);
        jPanel5.setLayout(jPanel5Layout);
        jPanel5Layout.setHorizontalGroup(
            jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel5Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jScrollPane5, javax.swing.GroupLayout.DEFAULT_SIZE, 355, Short.MAX_VALUE)
                .addContainerGap())
        );
        jPanel5Layout.setVerticalGroup(
            jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel5Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jScrollPane5, javax.swing.GroupLayout.PREFERRED_SIZE, 134, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(138, Short.MAX_VALUE))
        );

        jTabbedPane1.addTab("", new javax.swing.ImageIcon(getClass().getResource("/catch.png")), jPanel5); // NOI18N

        jLabel8.setFont(new java.awt.Font("Tahoma", 0, 12));
        jLabel8.setText("Owner:");

        ownerTextField.setEditable(false);
        ownerTextField.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N

        jLabel9.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
        jLabel9.setText("Id:");

        idTextField.setEditable(false);
        idTextField.setFont(new java.awt.Font("Tahoma", 0, 12));
        idTextField.setText("jTextField1");

        jComboBox1.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12" }));

        jComboBox2.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "50", "51", "52", "53", "54", "55", "56", "57", "58", "59" }));

        jComboBox3.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "AM", "PM" }));

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jTabbedPane1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 380, Short.MAX_VALUE)
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                        .addComponent(saveButton, javax.swing.GroupLayout.PREFERRED_SIZE, 68, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(cancelButton))
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jLabel8)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(ownerTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 88, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(jLabel9)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(idTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 75, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 17, Short.MAX_VALUE)
                        .addComponent(jComboBox1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jComboBox2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jComboBox3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel8)
                    .addComponent(ownerTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jComboBox1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jComboBox2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jComboBox3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel9)
                    .addComponent(idTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(jTabbedPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 341, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(cancelButton, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(saveButton))
                .addContainerGap())
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelButtonActionPerformed
        this.dispose();
    }//GEN-LAST:event_cancelButtonActionPerformed

    private void saveButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveButtonActionPerformed
        final JDialog dialog = this;

        SwingUtilities.invokeLater(new Runnable() {

            public void run() {
                // Validate the display
                if (!valid())
                    return;

                // Scrape the screen
                scrape();

                // Insert the elog
                // We need to insert the log first because if the log
                // is new its id will be -1 and the links won't look right.
                if (!insertElog()) {
                    JOptionPane.showMessageDialog(dialog, "Wow, log insertion failed!",
                            "Netlog", JOptionPane.ERROR_MESSAGE);

                    dispose();

                    return;
                }

                // Update the links
                if (!updateLinks()) {
                    JOptionPane.showMessageDialog(dialog, "Wow, update links failed!",
                            "Netlog", JOptionPane.ERROR_MESSAGE);

                    dispose();

                    return;
                }

                if(!insertHandoff()) {
                    JOptionPane.showMessageDialog(dialog, "Wow, handoff insert failed!",
                            "Netlog", JOptionPane.ERROR_MESSAGE);

                    dispose();

                    return;
                }

                JOptionPane.showMessageDialog(dialog, "Log id = " + elog.getId() + " saved successfully.",
                        "Netlog", JOptionPane.INFORMATION_MESSAGE);

                dialog.dispose();
            }
        });
    }//GEN-LAST:event_saveButtonActionPerformed

    private void addLinkButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addLinkButtonActionPerformed
        final ElogEditDialog parent = this;

        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                if(parent.userLinkComboBox.getSelectedIndex() == 0) {
                    JOptionPane.showMessageDialog(parent, "Select an owner.",
                            "Netlog", JOptionPane.ERROR_MESSAGE);
                    return;
                }
                ElogUser owner =
                        (ElogUser) parent.userLinkComboBox.getSelectedItem();

                LinkSelectDialog dialog = new LinkSelectDialog(parent,owner);

                dialog.setVisible(true);

                // Get the link elog, if there is one
                WorkletContext context = WorkletContext.getInstance();

                Elog alog = (Elog) context.take(LinkSelectDialog.TAG_LINK);

                if(alog == null)
                    return;

                // Put the new elog in the links table
                LinksTableModel model = (LinksTableModel) parent.linksTable.getModel();

                model.add(alog);

                model.refresh(elog);
            }

        });
    }//GEN-LAST:event_addLinkButtonActionPerformed

    private void addCommentButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addCommentButtonActionPerformed
        String text = this.commentTextArea.getText();

        if(text.length() == 0)
            return;

        Comment comment = new Comment();

        comment.setText(text);
        comment.setUserId(Helper.whoAmI(context).getId());

        CommentsTableModel model = (CommentsTableModel) this.commentsTable.getModel();

        model.getComments().add(comment);

        model.refresh();

        this.commentTextArea.setText("");
    }//GEN-LAST:event_addCommentButtonActionPerformed

    /**
     * Validates the entries on the display.
     * @return True if everything checks out
     */
    private boolean valid() {
        Integer id = elog.getId();

        if(this.workOrderTextField.getText().length() == 0 && id == -1) {
            String msg = "Work order field is blank.";
            msg += "\nProceed?";

            int n = JOptionPane.showConfirmDialog(
                    this,
                    msg,
                    "Confirm",
                    JOptionPane.YES_NO_OPTION);

            if (n == 1) {
                return false;
            }
        }

        if(this.descriptionTextArea.getText().length() == 0 && id == -1) {
            String msg = "Description field is blank.";
            msg += "\nProceed?";

            int n = JOptionPane.showConfirmDialog(
                    this,
                    msg,
                    "Confirm",
                    JOptionPane.YES_NO_OPTION);

            if (n == 1)
                return false;
        }

        if(this.workDoneTextArea.getText().length() == 0 && id == -1) {
            String msg = "Work done field is blank.";
            msg += "\nProceed?";

            int n = JOptionPane.showConfirmDialog(
                    this,
                    msg,
                    "Confirm",
                    JOptionPane.YES_NO_OPTION);

            if (n == 1) {
                return false;
            }
        }

        if(this.handoffMessageTextArea.getText().length() != 0)
        {
            if(this.userHandoffComboBox.getSelectedIndex() == 0 &&
                    this.tradeHandoffComboBox.getSelectedIndex() == 0) {
                String msg = "No user or trade selected for handoff!";

                JOptionPane.showMessageDialog(this, msg,"Netlog", JOptionPane.ERROR_MESSAGE);
                
                return false;
            }

        }

        if(this.userHandoffComboBox.getSelectedIndex() != 0 ||
                    this.tradeHandoffComboBox.getSelectedIndex() != 0)
        {
            if(this.handoffMessageTextArea.getText().length() == 0) {
                String msg = "Handoff has no message.\nProceed?";

                int n = JOptionPane.showConfirmDialog(
                        this,
                        msg,
                        "Confirm",
                        JOptionPane.YES_NO_OPTION);

                if(n == 1)
                    return false;
            }
        }

        return true;
    }

    /**
     * Create the handoff
     */
    private boolean insertHandoff() {
        // If the handoff already exists, it can't be updated.
        if(handoff.getId() != -1)
            return true;

        // If the handoff fields are not set, no handoff is requested
        if(this.userHandoffComboBox.getSelectedIndex() == 0 &&
                this.tradeHandoffComboBox.getSelectedIndex() == 0 &&
                this.handoffMessageTextArea.getText().length() == 0)
            return true;

        // This handoff is from me
        handoff.setFromId(me.getId());

        // ...in reference to this elog and repository
        handoff.setElogId(elog.getId());

        handoff.setReposTitle(me.getReposTitle());

        // ...to that user
        if(this.userHandoffComboBox.getSelectedIndex() != 0) {
            ElogUser toUser = (ElogUser) this.userHandoffComboBox.getSelectedItem();
            handoff.setToId(toUser.getId());
        }

        //...or that trade
        if(this.tradeHandoffComboBox.getSelectedIndex() != 0) {
            Trade trade = (Trade) this.tradeHandoffComboBox.getSelectedItem();
            handoff.setTradeId(trade.getId());
        }

        handoff.setMessage(this.handoffMessageTextArea.getText());

        boolean successful = Helper.insert(handoff, Handoffs.TITLE, context);

        return successful;
    }

    /**
     * Updates the links repository
     * @return True if the update succeeds
     */
    private boolean updateLinks() {
        // It's important to insert the links first because
        // all the new links get removed during insert.
        if(!insertLinks())
            return false;

        // Retire an unchecked links
        if(!retireLinks())
            return false;

        // Insert the log if it has become dirty, ie, through
        // changes to its audit as a result of managing its links
        boolean successful = true;
        
        if(dirty)
            successful = insertElog();

        return successful;
    }
    /**
     * Inserts new links into the repository.
     * @return True if insert succeeds
     */
    private boolean insertLinks() {
        // First, we get the additions and remove them from
        // the link states as we resolve them.

        // If the addition is disabled, we won't save it
        LinksTableModel model = (LinksTableModel) this.linksTable.getModel();

        ArrayList<Elog> additions = model.getAdditions();

        HashMap<Elog,Boolean> linkStates = model.getLinkStates();

        // Create links to this log and save them
        for(Elog alog : additions) {
            // Insert a new link if it is maked for save
            Boolean save = linkStates.get(alog);

            if(!save)
                continue;

            Link link = new Link(elog.getId(), elog.getReposTitle(), alog.getId(), alog.getReposTitle());

            if (!Helper.insert(link, Links.TITLE, context))
                return false;

            // Update audit for that elog
            Audit audit1 = new Audit();
            audit1.setStatus(alog.getStatus());
            audit1.setUserId(me.getId());
            audit1.setText("Linked to log id="+elog.getId()+" of user '"+me.getLogname()+"'.");
            alog.getAuditTrail().add(audit1);

            // Save the log so that the changes persist
            if(!Helper.insert(alog, alog.getReposTitle(),context))
                return false;

            // Update the audit for this elog (save the log later!!)
            Audit audit2 = new Audit();
            audit2.setStatus(elog.getStatus());
            audit2.setUserId(me.getId());
            ElogUser them = CIAHelper.toUser(alog.getReposTitle());
            audit2.setText("Linked to log id="+alog.getId()+" of user '"+them.getLogname()+"'.");
            elog.getAuditTrail().add(audit2);

            dirty = true;

            // We don't need that elog anymore
            linkStates.remove(alog);
        }

        return true;
    }
    
    /**
     * Removes links from the repository.
     * @return True of removal succeeds
     */
    private boolean retireLinks() {
        LinksTableModel model = (LinksTableModel) this.linksTable.getModel();

        HashMap<Elog,Boolean> linkStates = model.getLinkStates();
        HashMap<Elog,Link> elogLinks = model.getElogLinks();

        Set<Elog> elogs = linkStates.keySet();

        // Go through the links and everything here should
        // only be an existing link. If the link is flage
        // for removal, only then will we retire it.
        for(Elog alog : elogs) {
            // If the link state has not changed, there's
            // nothing to update
            if(linkStates.get(alog) == Boolean.TRUE)
                continue;

            // Destroy the link
            Link link = elogLinks.get(alog);

            if(!Helper.delete(link, Links.TITLE,context))
                return false;

            // Update audit for that elog (we destroyed the link to it)
            Audit audit1 = new Audit();

            audit1.setStatus(alog.getStatus());

            audit1.setUserId(me.getId());

            audit1.setText("Deleted link to log id="+elog.getId()+" of user '"+me.getLogname()+"'.");

            alog.getAuditTrail().add(audit1);

            // Save the log so that the changes persist
            if(!Helper.insert(alog, alog.getReposTitle(),context))
                return false;

            // Update the audit for this elog (we destroyed the link to it)
            Audit audit2 = new Audit();
            audit2.setStatus(elog.getStatus());
            audit2.setUserId(me.getId());
            ElogUser them = CIAHelper.toUser(alog.getReposTitle());
            audit2.setText("Deleted link to log id="+alog.getId()+" of user '"+them.getLogname()+"'.");

            elog.getAuditTrail().add(audit2);

            dirty = true;
        }

        return true;
    }

    private boolean insertElog() {
        String repos = elog.getReposTitle();

        boolean successful = Helper.insert(elog, repos, context);

        return successful;
    }

    private void scrape() {
        elog.setDescription(this.descriptionTextArea.getText());
        elog.setRequestId(this.workOrderTextField.getText());
        elog.setStatus((Elog.Status) this.statusComboBox.getSelectedItem());
        elog.setWorkDone(this.workDoneTextArea.getText());

        if (this.typeCheckBox.isSelected()) {
            elog.setType(Elog.Type.UNUSUAL);
        } else {
            elog.setType(Elog.Type.NORMAL);
        }
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton addCommentButton;
    private javax.swing.JButton addLinkButton;
    private javax.swing.JButton cancelButton;
    private javax.swing.JTextArea commentTextArea;
    private javax.swing.JTable commentsTable;
    private javax.swing.JTextArea descriptionTextArea;
    private javax.swing.JTextField handoffDateTextField;
    private javax.swing.JTextField handoffIdTextField;
    private javax.swing.JTextArea handoffMessageTextArea;
    private javax.swing.JTextField idTextField;
    private javax.swing.JComboBox jComboBox1;
    private javax.swing.JComboBox jComboBox2;
    private javax.swing.JComboBox jComboBox3;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel10;
    private javax.swing.JLabel jLabel11;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jLabel6;
    private javax.swing.JLabel jLabel7;
    private javax.swing.JLabel jLabel8;
    private javax.swing.JLabel jLabel9;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JPanel jPanel3;
    private javax.swing.JPanel jPanel4;
    private javax.swing.JPanel jPanel5;
    private javax.swing.JPanel jPanel6;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JScrollPane jScrollPane3;
    private javax.swing.JScrollPane jScrollPane4;
    private javax.swing.JScrollPane jScrollPane5;
    private javax.swing.JScrollPane jScrollPane6;
    private javax.swing.JScrollPane jScrollPane7;
    private javax.swing.JTabbedPane jTabbedPane1;
    private javax.swing.JTable jTable3;
    private javax.swing.JTable linksTable;
    private javax.swing.JTextField ownerTextField;
    private javax.swing.JButton saveButton;
    private javax.swing.JComboBox statusComboBox;
    private javax.swing.JComboBox tradeHandoffComboBox;
    private javax.swing.JCheckBox typeCheckBox;
    private javax.swing.JComboBox userHandoffComboBox;
    private javax.swing.JComboBox userLinkComboBox;
    private javax.swing.JTextArea workDoneTextArea;
    private javax.swing.JTextField workOrderTextField;
    // End of variables declaration//GEN-END:variables
}
